package constraint;

import java.util.ArrayList;
import java.util.List;

import model.MClass;
import model.MDefinedObject;
import model.MObject;
import model.MUndefinedObject;
import choco.Constraint;
import choco.integer.IntExp;
import expression.MIntVar;
import expression.MObjectIdent;

public class MObjectClass extends MConstraint {
	private MObject mObject;
	private MClass mClass;

	public MObjectClass(MObject o, MClass c) {
		super(o.getCore());
		mObject = o;
		mClass = c;
	}
	
	public MObject getObject() {
		return mObject;
	}

	public Constraint constraint() {
		if (mObject instanceof MDefinedObject) {
			MDefinedObject obj = (MDefinedObject)mObject;
			if (obj.getMClass() == mClass)
				return getCore().getProblem().TRUE;
			else
				return getCore().getProblem().FALSE;
		}
		else {
			MUndefinedObject obj = (MUndefinedObject)mObject;
			MObjectIdent objEval = obj.getIdent().eval();
			Constraint lower = getCore().getProblem().geq(objEval.getVariable(), mClass.getFirstObject());
			IntExp temp = getCore().getProblem().plus(mClass.getFirstObject(), mClass.getSelfCardinality().eval().intExp());
			Constraint upper = getCore().getProblem().leq(objEval.getVariable(), temp);
			return getCore().getProblem().and(lower, upper);			
		}
	}

	public List<MIntVar> getVariables() {
		List<MIntVar> vars = new ArrayList<MIntVar>();
		if (mObject instanceof MUndefinedObject) {
			MUndefinedObject obj = (MUndefinedObject)mObject;
			
			vars.add(obj.getIdent());
			vars.add(mClass.getSelfCardinality());
		}
		return vars;
	}

	public String toText() {
		return mObject.toText() + "::" + mClass.getName();
	}

	public MConstraint eval() {
		return this;
	}
}
